package com.id.coinscleaner.utils

import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager
import android.database.ContentObserver
import android.graphics.Bitmap
import android.graphics.Color
import android.media.MediaScannerConnection
import android.net.Uri
import android.os.Build
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore
import androidx.core.content.ContextCompat
import com.id.coinscleaner.App.Companion.DataStore
import com.id.coinscleaner.App.Companion.appContext
import java.io.File
import java.io.FileOutputStream
import java.util.*
import kotlin.system.exitProcess

class ScreenshotContentResolver {

    private val keywords = arrayOf("screenshot", "screen_shot")
    private val keywordsVideo = arrayOf("screenrecording", "screen_recording", "screenrecord", "screen_record")

    private val contentObserver by lazy {
        object : ContentObserver(Handler(Looper.getMainLooper())) {
            override fun onChange(selfChange: Boolean, uri: Uri?) {
                super.onChange(selfChange, uri)

                if (!hasReadStoragePermission) return

                val path = getContentResolverFilePath(uri)
                if (path.isNullOrEmpty()) {
                    return
                }
                Events.sendEvent("file_change", "path" to path)
                if (isScreenshotPath(path)) {
                    onScreeHappen(path, true)
                } else if (isScreenRecordPath(path)) {
                    onScreeHappen(path, false)
                }

            }
        }
    }

    private fun onScreeHappen(path: String?, isShot: Boolean) {
        Events.sendEvent("snapshot_yes")

        path?.let {
            //记录起来，下次不再展示恐吓页面了
            updateScreenshot(true)

            //适配OPPO机型
            if (isShot && Build.BRAND == "OPPO") {
                Handler(Looper.getMainLooper()).postDelayed({
                    try {
                        val bitmap = Bitmap.createBitmap(
                            getScreenWidthDp(), getScreenHeightDp(), Bitmap.Config.ARGB_8888
                        )
                        bitmap.eraseColor(Color.parseColor("#FFFFFF"));

                        val file = File(path)
                        val out = FileOutputStream(file)
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)
                        out.flush()
                        out.close()
                        //保存图片后发送广播通知更新数据库
                        val uri: Uri = Uri.fromFile(file)
                        appContext.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri))
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                    exitProcess(0)
                }, 5500)
            } else {
                deleteScreenFile(path)
                Handler(Looper.getMainLooper()).postDelayed({ exitProcess(0) }, 300)
            }
        }
    }

    private fun deleteScreenFile(path: String) {
        try {
            val file = File(path)
            file.delete()
            //保存图片后发送广播通知更新数据库
            MediaScannerConnection.scanFile(appContext, arrayOf(file.toString()), null, null)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


    private fun isScreenshotPath(path: String?): Boolean {
        path?.lowercase(Locale.getDefault())?.let {
            keywords.forEach { key ->
                if (it.contains(key)) return true
            }
        }
        return false
    }

    private fun isScreenRecordPath(path: String?): Boolean {
        path?.lowercase(Locale.getDefault())?.let {
            keywordsVideo.forEach { key ->
                if (it.contains(key)) return true
            }
        }
        return false
    }

    @SuppressLint("Range")
    private fun getContentResolverFilePath(uri: Uri?): String? {
        if (uri == null) return null
        try {
            val cursor = appContext.contentResolver.query(
                uri,
                arrayOf(
                    MediaStore.Images.Media.DISPLAY_NAME,
                    MediaStore.Images.Media.DATA,
                    MediaStore.Video.Media.DISPLAY_NAME,
                    MediaStore.Video.Media.DATA,
                ),
                null, null, null
            )
            if (cursor != null && cursor.moveToFirst()) {
                val path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
                cursor.close()
                return path
            }
        } catch (e: Throwable) {
        }
        return null
    }

    fun register() {
        appContext.contentResolver.registerContentObserver(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, contentObserver
        )
        appContext.contentResolver.registerContentObserver(
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, contentObserver
        )
    }

    fun unregister() {
        appContext.contentResolver.unregisterContentObserver(contentObserver)
    }

    private fun getScreenWidthDp(): Int {
        val displayMetrics = appContext.resources.displayMetrics
        return displayMetrics.widthPixels * 160 / displayMetrics.densityDpi
    }

    private fun getScreenHeightDp(): Int {
        val displayMetrics = appContext.resources.displayMetrics
        return displayMetrics.heightPixels * 160 / displayMetrics.densityDpi
    }

    companion object {
        const val ScreenshotDid = "ScreenshotDid"
        internal fun updateScreenshot(value: Boolean) {
            DataStore.encode(ScreenshotDid, value)
        }

        val isScreenshot: Boolean get() = DataStore.decodeBool(ScreenshotDid)
    }

}

val hasReadStoragePermission
    get() = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
val hasWriteStoragePermission
    get() = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)

fun checkSelfPermission(permission: String): Boolean {
    return ContextCompat.checkSelfPermission(appContext, permission) == PackageManager.PERMISSION_GRANTED
}